package pure.ui 
{
	import pure.ui.*;
	import pure.ui.core.*;
	import pure.ui.skins.*;
	import flash.display.Bitmap;
	import flash.events.*;
	import flash.geom.*;

	/**
	 * 滑动器
	 * @author des
	 * <皮肤种类> ---- SliderSkin
	 * 
	 */
	
public class Slider extends Component 
{
	public function Slider(x:Number,y:Number,size:Point=null,skin:ISkin=null,isVertical:Boolean=true) 
	{
		this._isVertical = isVertical;
		super(x, y, skin);
		// 初始化滑动器大小
		if (size) 
		{
			_initSliderSize(size.x, size.y);
		}
		else
		{
			if (this._isVertical)
			{
				_initSliderSize(DEFAUT_W, DEFAUT_H);
			}
			else
			{
				_initSliderSize(DEFAUT_H, DEFAUT_W);
			}
		}
	}
	
	
	
	/*defaut*/
	
	protected static const DEFAUT_W:Number = 15;	// 默认宽度
	
	protected static const DEFAUT_H:Number = 150;	// 默认高度
	
	
	/*model*/
	
	protected var _status:Number=0;	// 精确至0.01
	
	protected var _min:Number =0;	// 非负数
	
	protected var _max:Number =100;	// 非负数
	
	
	/*cache*/
	
	protected var _thumb:Button;
	
	protected var _track:Bitmap;

	protected var _isVertical:Boolean;	// 该次初始化后将无法改变
	
	protected var ____changeObserver:Function;
	
	protected var _oldMouse:Number;

	
	

	/**
	 * 滑动按钮大小
	 * @param w			按钮宽度
	 * @param h			按钮高度
	 **/
	public function setThumbSize(w:Number, h:Number):void
	{
		this._thumb.setSize(w, h);
	}
	
	/**
	 * 滑动值范围
	 * @param min		最小值
	 * @param max		最大值
	 **/
	public function setRange(min:Number, max:Number):void
	{
		this.min = min;
		this.max = max;
	}
	
	/**
	 * 滑动变化回调
	 * @param observer		回调方法
	 **/
	public function setObserverChange(observer:Function):void
	{
		____changeObserver = observer;
	}
	
	/**
	 * 毁灭
	 */
	override public function destroy():void
	{
		super.destroy();
		_thumb.destroy();
		_track.bitmapData = null;
		_track = null;
		____changeObserver = null;
	}
	
	
	
	
	
	
	/* ----------------------------------------------------    get / set    ----------------------------------------------------*/
	
	
	
	

	
	// 滑动器皮肤
	override public function set skin(value:ISkin):void
	{
		if (!value is SliderSkin)
		{
			throw new Error('Slider::skin - 皮肤类型错误！');
		}
		super.skin = value;
		if (value)
		{
			this._thumb.skin = value.getSkin('thumb');
		}
		else
		{
			this._thumb.skin = null;
		}
	}
	
	
	// 滑动值(状态值) - 精确至0.01
	public function set status(value:Number):void
	{
		if (this._status != value)
		{
			this._status = int(value * 100) / 100;
			if (this._status < this._min) 
			{
				this._status = this._min;
			}
			else if (this._status > this._max) 
			{
				this._status = this._max;
			}
			_rejustThumbPosition();
			if (____changeObserver != null) 
			{
				____changeObserver();
			}
		}
	}
	
	public function get status():Number
	{
		return this._status;
	}
	
	
	// 最小值
	public function set min(value:Number):void
	{
		if (this._min != value) 
		{
			if (value < 0) 
			{
				value = 0;
			}
			else if (value > this._max)
			{
				value = this._max;
			}
			this._min = value;
			if (this._status < this._min)
			{
				this.status = this._min;
			}
			update();
		}
	}
	
	public function get min():Number
	{
		return this._min;
	}
	
	
	// 最大值
	public function set max(value:Number):void
	{
		if (this._max != value)
		{
			if (value < this._min)
			{
				value = this._min;
			}
			this._max = value;
			if (this._status > this._max)
			{
				this.status = this._max;
			}
			update();
		}
	}
	
	public function get max():Number
	{
		return this._max;
	}
	
	
	
	
	
	/* ----------------------------------------------------    private    ----------------------------------------------------*/
	
	
	
	
	
	/**
	 * 初始化滑动跑道×滑动按钮大小
	 * <TODO>初始化让按钮与跑道宽度相等
	 * @param w			滑动跑道宽度
	 * @param h			滑动跑道高度
	 **/
	protected function _initSliderSize(w:Number,h:Number):void
	{
		super.setSize(w, h);
		// 垂直型
		if (this._isVertical) 
		{
			this._thumb.setSize(w, w);	
		}	
		// 水平型
		else 
		{
			this._thumb.setSize(h, h);
		}
	}
	
	
	/**
	 * 子元素
	 */
	override protected function _addChildren():void
	{
		super._addChildren();
		
		// 滑动轨道
		this._track = new Bitmap();
		addChild(this._track);
		this.addEventListener(MouseEvent.MOUSE_DOWN, ____onTrackDown);
		
		// 滑动按钮
		this._thumb = new Button();
		addChild(this._thumb);
		
		// 观察改变
		this._thumb.addEventListener(MouseEvent.MOUSE_DOWN, ____onThumbDown);
	}
		
	/**
	 * 按滑动轨道
	 */
	protected function ____onTrackDown(e:MouseEvent):void
	{
		if (this._isVertical) 
		{
			this._thumb.y = this.mouseY;
			if (this._thumb.y < this._thumb.height * 0.5)
			{
				this._thumb.y = this._thumb.height * 0.5;
			}
			else if (this._thumb.y > this._height - this._thumb.height * 0.5) 
			{
				this._thumb .y = this._height - this._thumb.height * 0.5;
			}
		}
		else
		{
			this._thumb.x = this.mouseX;
			if (this._thumb.x < this._thumb.width * 0.5)
			{
				this._thumb.x = this._thumb.width * 0.5;
			}
			else if (this._thumb.x > this._width - this._thumb.width * 0.5)
			{
				this._thumb .x = this._width - this._thumb.width * 0.5;
			}
		}
		_rejustStatus();
	}

	/**
	 * 按thumb
	 */
	protected function ____onThumbDown(e:MouseEvent):void
	{
		stage.addEventListener(MouseEvent.MOUSE_UP, ____onMouseUp);
		stage.addEventListener(MouseEvent.MOUSE_MOVE, ____onMouseMove);
		_oldMouse = this._isVertical? this.mouseY:this.mouseX;
		e.stopPropagation();
	}
	
	/**
	 * 放开thumb
	 */
	protected function ____onMouseUp(e:MouseEvent):void
	{
		stage.removeEventListener(MouseEvent.MOUSE_UP, ____onMouseUp);
		stage.removeEventListener(MouseEvent.MOUSE_MOVE,____onMouseMove);
	}

	/**
	 * 拖动thumb
	 */
	protected function ____onMouseMove(e:MouseEvent):void
	{
		e.updateAfterEvent();
		
		// 垂直滑动
		if (this._isVertical)
		{
			if (this.mouseY < 0 || this.mouseY > this._height)
			{
				return;
			}
			this._thumb.y -= _oldMouse-this.mouseY;
			_oldMouse = this.mouseY;
			if (this._thumb.y < this._thumb.height * 0.5)
			{
				this._thumb.y = this._thumb.height * 0.5;
			}
			else if (this._thumb.y > this._height - this._thumb.height*0.5) 
			{
				this._thumb.y = this._height - this._thumb.height*0.5;
			}
		}
		
		// 水平滑动
		else 
		{
			if (this.mouseX < 0 || this.mouseX > this._width) 
			{
				return;
			}
			this._thumb.x -= _oldMouse-this.mouseX;
			_oldMouse = this.mouseX;
			if (this._thumb.x < this._thumb.width * 0.5)
			{
				this._thumb.x = this._thumb.width * 0.5;
			}
			else if (this._thumb.x > this._width - this._thumb.width*0.5) 
			{
				this._thumb.x = this._width - this._thumb.width*0.5;
			}
		}
		_rejustStatus();
	}
	
	/**
	 * 调整滑动值
	 */
	protected function _rejustStatus():void
	{
		var range:Number;
		if (this._isVertical)
		{
			range = this._height - this._thumb.height;
			this.status = (range-this._thumb.y + this._thumb.height * 0.5) / range * (_max - _min) + _min;
		}
		else 
		{
			range = this._width - this._thumb.width;
			this.status = (this._thumb.x - this._thumb.width * 0.5) / range * (_max - _min) + _min;
		}
	}
	
	/**
	 * 调整thumb位置
	 */
	protected function _rejustThumbPosition():void
	{
		var range:Number;
		// 比率
		var ratio:Number = (this._status - this._min) / (this._max - this._min);
		if (this._isVertical)
		{
			range = this._height - this._thumb.height;
			this._thumb.move(_width * 0.5 , this._thumb.height * 0.5 + range * (1 - ratio));
		}
		else
		{
			range = this._width - this._thumb.width;
			this._thumb.move(this._thumb.width * 0.5 + ratio * range, _height * 0.5);
		}
	}

	/**
	 * 绘制
	 */
	override protected function _draw():void
	{
		if (_skin&&_getBitmap("track")) 
		{
			_skip("track");
			_clear();
		}
		else
		{
			if (this._track.bitmapData) 
			{
				this._track.bitmapData = null;
			}
			_definition = null;
			_drawNoSkin(0x77dc77, 0.6, 1);
		}
		_rejustThumbPosition();
	}
	
	/**
	 * 更换位图
	 * @param definition		类定义名称
	 **/
	override protected function _skip(definition:String):void
	{
		// 滑动跑道大小变化始终需要重绘
		this._track.bitmapData = _getBitmap(definition);
		this._definition = this._skin[definition];
	}

	
}

}